package philbot;

import java.util.HashMap;
import java.util.Map;
/**
 * The representation of the transposition table
 * Unsynchronized.  Currently not safe to use concurrently
 * @author philip
 *
 */
public class TransTable {
	/**
	 * Entries in the transposition table.  Stores a depth and a value
	 * @author philip
	 *
	 */
	public static class Entry{
		public int value;
		public int depth;
		Entry(int value, int depth){
			this.value = value;
			this.depth = depth;
		}
	}
	private Map<AbstractPosition,Entry> exacts;
	private Map<AbstractPosition,Entry> lowers;
	private Map<AbstractPosition,Entry> highers;
	/**
	 * Builds a fresh transposition table
	 */
	public TransTable(){
		this.exacts = new HashMap<AbstractPosition,Entry>();
		this.lowers = new HashMap<AbstractPosition,Entry>();
		this.highers = new HashMap<AbstractPosition,Entry>();
	}
	/**
	 * Used for "exact" positions
	 * @param p the position
	 * @param minDepth the minimum depth considered sucesful
	 * @return the stored eval number
	 */
	public Integer getExact(AbstractPosition p, int minDepth){
		Entry e = exacts.get(p);
		if((e == null)||(e.depth < minDepth)){
			return null;
		}else{
			return e.value;
		}
			
	}
	/**
	 * Set an exact position
	 * @param p the position
	 * @param depth the depth it is evaluated to
	 * @param value the evaluated value
	 */
	public void setExact(AbstractPosition p, int depth, int value){
		exacts.put(p, new Entry(value,depth));
	}
	/**
	 * Used for lower bounds
	 * @param p the position
	 * @param minDepth the minimum depth considered sucesful
	 * @return the stored eval number
	 */
	public Integer getLow(AbstractPosition p, int minDepth){
		Entry e = lowers.get(p);
		if((e == null)||(e.depth < minDepth)){
			return null;
		}else{
			return e.value;
		}
	}
	/**
	 * Set a lower bound
	 * @param p the position
	 * @param depth the depth it is evaluated to
	 * @param value the evaluated value
	 */
	public void setLow(AbstractPosition p, int depth, int value){
		lowers.put(p, new Entry(value,depth));
	}
	/**
	 * Used for upper bounds
	 * @param p the position
	 * @param minDepth the minimum depth considered sucesful
	 * @return the stored eval number
	 */
	public Integer getHigh(AbstractPosition p, int minDepth){
		Entry e = highers.get(p);
		if((e == null)||(e.depth < minDepth)){
			return null;
		}else{
			return e.value;
		}
	}
	/**
	 * Set an upper bound
	 * @param p the position
	 * @param depth the depth it is evaluated to
	 * @param value the evaluated value
	 */
	public void setHigh(AbstractPosition p, int depth, int value){
		highers.put(p, new Entry(value,depth));
	}

}
